Skip to content

perf: support fine-grained activation offloading - #2279

Merged
terrykong merged 34 commits into
mainfrom
sj/fine-grained-activation-offload
Aug 17, 2026
Merged

perf: support fine-grained activation offloading#2279
terrykong merged 34 commits into
mainfrom
sj/fine-grained-activation-offload

Conversation

@seonjinn

@seonjinn seonjinn commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds first-class fine-grained activation offloading for the Megatron policy backend.

  • Exposes fine_grained_activation_offloading and offload_modules in NeMo RL configuration.
  • Applies explicit enable/disable overrides to the Megatron model provider and validates invalid module combinations.
  • Preserves Megatron Core's activation-offload warmup/cache state across forward-only GRPO logprob passes, so a no-grad pass does not consume the training warmup.
  • Documents configuration, supported module names, and compatibility constraints.

This is activation offloading and is independent of optimizer_cpu_offload.

Usage

MoE example:

policy:
  megatron_cfg:
    enabled: true
    cuda_graph_impl: transformer_engine
    env_vars:
      NVTE_CPU_OFFLOAD_V1: "1"
    fine_grained_activation_offloading: true
    offload_modules:
      - moe_act

For dense models, use supported dense modules such as core_attn and attn_proj. The pinned Megatron Core also supports full_iteration, but NeMo RL does not yet wire its full-iteration capture/replay lifecycle; the supported NeMo RL path for the dense pair is currently transformer_engine. Megatron Bridge/Megatron Core validation enforces the remaining Transformer Engine, module, and incompatible-feature constraints.

Validation

Unit and contract tests

  • Pre-Tyche job 2573881: 56/56 focused Megatron setup/train lifecycle tests passed against runtime head 01398467224921c058a70702cb4a8285eb98fc71.
  • Formatting, YAML parsing, Ruff, compile, and diff checks passed for the changed files.

GB200 functional validation

Qwen3-30B-A3B GRPO, 4 nodes × 4 GB200, BF16, TP1/PP1/EP16, GBS 2048, MBS 1, sequence length 4096:

Job Cell Result Activation-offload evidence
2677648 ON 3/3 updates, exit 0 finite loss/grad; moe_act offload reported on all 16 ranks, 3.17–5.08 GiB/rank
2677799 OFF 10/10 updates, exit 0 no activation-offload summary, as expected
2677805 ON 10/10 updates, exit 0 finite loss/grad; 70.50 GiB aggregate selected offload volume across 16 ranks

Memory evidence

Memory metric OFF ON ON vs OFF
Selected activation volume copied to CPU during MCore warmup* 0 GiB (disabled) 70.50 GiB aggregate; 4.41 GiB/rank mean across 16 ranks +70.50 GiB selected for offload
Policy-phase peak GPU memory Not measured Not measured No numerical peak-memory reduction claimed

* This is the summed byte volume of activation groups selected for CPU offload, not instantaneous GPU residency or an ON-vs-OFF allocator peak-memory delta.

Descriptive timing for the single matched OFF/ON pair, steps 2–9 (n=8):

Metric OFF ON ON vs OFF
E2E step time 175.80 s 179.61 s +2.2%
Policy training time 79.02 s 82.76 s +4.7%
Reference-policy logprob time 19.82 s 19.35 s -2.4%
Generation time 70.52 s 70.75 s +0.3%
E2E throughput/GPU 2365.8 tok/s 2319.9 tok/s -1.9%
Policy throughput/GPU 5269.1 tok/s 5041.9 tok/s -4.3%
Reference-policy logprob throughput/GPU 21023.2 tok/s 21588.0 tok/s +2.7%

This validates the NeMo RL activation-offload path, reference-policy logprob transition, and policy training, and confirms that Megatron Core offloads moe_act on every rank. This recipe sets force_on_policy_ratio=true, so current-policy prev_logprobs was skipped in these cluster jobs; the current-policy forward-only lifecycle is covered by focused unit tests here, not by this GB200 run.

The pair does not establish a stable speedup or policy peak-memory reduction: this is one replica, the arms ran on different node groups, and the available Ray GPU samples combine colocated rollout and training. The reported offload volume is selected activation volume, not measured peak-memory savings. Replicated policy-phase allocator measurements are required before making a memory-benefit claim.

Self-review

Ran /review-pr-team with a full diff review plus an adversarial second pass. The review found no remaining correctness defect in the live runtime head. Addressed review feedback includes explicit disable semantics, valid dense/MoE module validation, forward-only lifecycle preservation, documentation/config discoverability, and NUMA-aware CPU affinity/memory binding through bind_to_gpu_numa(local_rank).

Before your PR is "Ready for review"

  • Read and followed the contributor guidelines.
  • Added focused unit/config tests.
  • Ran unit/contract and GB200 functional validation.
  • Added/updated user documentation and exemplar configuration.

@seonjinn
seonjinn requested review from a team as code owners April 17, 2026 04:44
@copy-pr-bot

copy-pr-bot Bot commented Apr 17, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@seonjinn
seonjinn requested review from a team as code owners April 17, 2026 05:11
Exposes Megatron-Core fine_grained_activation_offloading and
offload_modules through PolicyConfig so training can offload specific
submodule activations (moe_act, core_attn, qkv_linear, mlp_norm,
attn_norm) to CPU. Works for both dense and MoE models. Validation of
module names is left to Megatron.

Signed-off-by: sna <sna@nvidia.com>
@seonjinn
seonjinn force-pushed the sj/fine-grained-activation-offload branch from 8a2292d to feee53e Compare April 17, 2026 07:08
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test feee53e

@seonjinn seonjinn self-assigned this Apr 17, 2026
@seonjinn
seonjinn requested a review from terrykong April 17, 2026 21:10

@terrykong terrykong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Nice feature addition — well-scoped passthrough to Megatron for fine-grained activation offloading. A few doc corrections and suggestions below.

Performance Evidence

This PR adds a memory-reduction feature but the description doesn't include benchmark numbers. Could you share peak GPU memory (GiB) and tokens/sec with and without activation offloading for a representative config (e.g. a MoE model with ["moe_act"] offloading)? Even a single run would help users know what to expect. A reference to the upstream Megatron-LM feature guide is also welcome.

Documentation

No user-facing docs added under docs/. Consider adding a brief section or pointer to the upstream Megatron-LM activation offloading guide.

Tests (optional nit)

Zero test coverage for the new validation logic. The existing TestApplyPerformanceConfig class in tests/unit/models/megatron/test_megatron_setup.py would be a natural home for a happy-path test (valid config sets attributes) and error-path test (empty list raises ValueError).

Generated by Claude Code

Comment thread nemo_rl/models/policy/__init__.py Outdated
Comment thread nemo_rl/models/megatron/setup.py Outdated
Comment thread nemo_rl/models/megatron/setup.py
Comment thread nemo_rl/models/megatron/setup.py Outdated
seonjinn and others added 3 commits April 23, 2026 14:31
Co-authored-by: Terry Kong <terryk@nvidia.com>
Signed-off-by: Seonjin <sna@nvidia.com>
Co-authored-by: Terry Kong <terryk@nvidia.com>
Signed-off-by: Seonjin <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test c7aae0d

seonjinn added 2 commits May 14, 2026 14:16
A stray closing parenthesis after the raise ValueError block caused a
SyntaxError, blocking the ruff/ruff-format pre-commit hooks in CI.

Signed-off-by: sna <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test daab28b

Signed-off-by: sna <sna@nvidia.com>
@seonjinn
seonjinn requested a review from a team as a code owner May 15, 2026 18:52
@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label May 15, 2026
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test d6cd6bc

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test bcccabf

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 08d121d

@seonjinn

Copy link
Copy Markdown
Contributor Author

@terrykong Can you review this PR when you have a chance?

@terrykong

Copy link
Copy Markdown
Collaborator

Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 2f39df6

Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>

@seonjinn seonjinn left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review completed with /review-pr-team using a full base-to-head review and an adversarial second pass.

Reviewed areas:

  • NeMo-RL config/provider propagation and explicit disable semantics
  • pinned Megatron Bridge/Megatron-Core validation and module compatibility
  • forward-only current/reference-logprob lifecycle versus activation-offload warmup/cache state
  • exception restoration and VPP shared/distinct-config behavior
  • documentation, exemplar/reference configs, unit coverage, and GB200 evidence

No remaining runtime correctness defect was found in the live PR head 01398467224921c058a70702cb4a8285eb98fc71. All six outstanding review threads were re-verified against that exact head, replied to with their fixing commit, and resolved. Terry's NUMA concern is covered by bind_to_gpu_numa(local_rank) from 9e01af64b3891e5bcc01885e10e9ca185b3e3690, which applies CPU affinity and NUMA memory binding to every Megatron worker.

The self-review found two documentation/config gaps: clarify that NeMo-RL currently supports the dense offload pair through the Transformer Engine CUDA-graph path even though pinned MCore also permits full_iteration, and add the disabled defaults to the standalone RM exemplar/reference config. Both are fixed in signed fork commit f651ac00ffc8a4cbe83a6abe626d6bea3f788325; Lyris job 2680213 validated its RM reference-config contract on Linux (1 passed, 13 deselected). The current PR branch is hosted in NVIDIA-NeMo/RL, so a maintainer must integrate that fork commit into this PR head.

GB200 validation and honest claim boundaries are now documented in the PR body. The Qwen3-30B-A3B ON arm offloaded nonzero moe_act volume on all 16 ranks and completed 3-step and 10-step lifecycle gates with finite training metrics. The single matched pair did not show a speedup, and allocator peak memory was not measured, so no stable throughput or peak-memory benefit is claimed.

@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test 0139846

@seonjinn

Copy link
Copy Markdown
Contributor Author

Correction to the self-review evidence boundary: the GB200 recipe uses loss_fn.force_on_policy_ratio=true, so it skipped current-policy prev_logprobs and executed the reference-policy logprob path. The cluster evidence therefore validates reference-logprob → policy-training lifecycle; current-policy forward-only lifecycle is covered by the focused unit tests, not these three jobs. The PR body has been corrected accordingly.

@seonjinn

Copy link
Copy Markdown
Contributor Author

Scope clarification: the self-review follow-up f651ac00f contains only documentation and RM exemplar/reference defaults; it has no runtime implementation change. To keep this PR functionally minimal, it is not required for integration. The activation-offload runtime fixes and focused lifecycle tests are already in the live PR head 01398467224921c058a70702cb4a8285eb98fc71. The PR body has been updated accordingly.

…c-20260813

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

Copy link
Copy Markdown
Contributor Author

/ok to test ea09321

ghost left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Team review of the activation-offloading feature — seven agents over the diff, upstream Megatron-LM/Bridge sources at the pinned SHAs, and the full PR thread history, followed by an adversarial pass that challenged every finding.

Overall: this is a well-built PR and close to ready. The _suspend_activation_offload_for_forward_only context manager is correctly shaped — module-level, fast path first, restore-on-exception right, and it matches MCore's own pre/post-warmup-hook idiom. The 300 lines of new tests need no GPU, no Ray, and no real Megatron model, which is a genuinely good seam. All eleven earlier review threads check out as fixed at head. The knob defaults to false in every exemplar, so there is no regression risk for anyone who does not opt in.

One item I would hold for: the PPO value worker's forward-only pass never enters the new context manager, and this PR ships the value.megatron_cfg keys that make that path reachable. Details inline on train.py.

The rest is one narrow None-vs-[] regression, one docs correction worth making (the CUDA-graph requirement is stated unconditionally but only applies when CUDA graphs are on), and a handful of nits you should feel free to take or leave.

On performance evidence: the GB200 validation and the explicit statement that it does not establish a speedup or a peak-memory reduction are the honest way to present this, and that is appreciated rather than criticized. The one gap worth a follow-up, whenever convenient and not as a merge condition: the cluster runs used force_on_policy_ratio=true, so the current-policy forward-only path — the reason the new context manager exists — was only exercised by mocked unit tests. A short GRPO run with force_on_policy_ratio=false, plus torch.cuda.max_memory_allocated() on and off, would both close that gap and give users a number to decide on. If a config that OOMs with the flag off and completes with it on is easy to produce, that single data point would justify the feature better than anything else.

Two notes on the record, neither a defect. The NUMA concern from the earlier thread is genuinely closed by bind_to_gpu_numa on the Megatron worker path — but the crediting commit 9e01af64b is #2613 (Youngeun Kwon), already on main; this PR touches no worker files. And the fork commit f651ac00f does not need maintainer integration: the exemplar coverage here already matches the convention set by the nearest sibling key, so its only genuinely useful half is the docs correction flagged inline, which you can push directly.

Also checked and cleared, so they do not resurface: MCore's own validation is not bypassed (setup.py:675 re-runs __post_init__() after the assignments, so bad module names and a bare attn_proj are caught upstream — no need to duplicate those checks); the new unconditional PipelineOffloadManager import is safe at the pin; model_overrides cannot silently clobber the new keys; and the num_moe_experts guard is live and adds coverage MCore genuinely lacks.

Note: repo linters could not be run in this environment (the lockfile is linux-only and this host is macOS), so there is no lint evidence in either direction.

Generated by Claude Code

Comment thread nemo_rl/models/megatron/train.py Outdated
Comment thread nemo_rl/models/megatron/setup.py Outdated
Comment thread docs/design-docs/training-backends.md Outdated
Comment thread tests/unit/models/megatron/test_megatron_setup.py Outdated
Comment thread nemo_rl/models/megatron/setup.py Outdated
Comment thread examples/configs/ppo_math_1B.yaml
seonjinn added 2 commits August 14, 2026 23:34
Signed-off-by: seonjinn <sna@nvidia.com>
…c-20260813

Signed-off-by: seonjinn <sna@nvidia.com>

# Conflicts:
#	examples/configs/distillation_math.yaml
#	examples/configs/distillation_math_megatron.yaml
#	examples/configs/dpo.yaml
#	examples/configs/grpo_math_1B.yaml
#	examples/configs/grpo_math_1B_megatron.yaml
#	examples/configs/sft.yaml
#	tests/unit/reference_configs/distillation_math.yaml
#	tests/unit/reference_configs/dpo.yaml
#	tests/unit/reference_configs/grpo_math_1B.yaml
#	tests/unit/reference_configs/sft.yaml
@seonjinn

ghost commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test fef2afb

Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn

ghost commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 6a4f1fc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:L1 Run doctests, unit tests, and functional tests Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants